package com.simple.simple_view.handler.mq;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.rabbitmq.client.Channel;
import com.simple.simple_view.domain.dto.FavoriteDto;
import com.simple.simple_view.domain.entity.UserLikeVideo;
import com.simple.simple_view.domain.system.RabbitMQConstant;
import com.simple.simple_view.domain.system.RedisSystemParam;
import com.simple.simple_view.domain.system.SystemParam;
import com.simple.simple_view.service.HotVideoService;
import com.simple.simple_view.service.UserLikeVideoService;
import com.simple.simple_view.service.impl.UserServiceImpl;
import com.simple.simple_view.service.impl.VideoServiceImpl;
import com.simple.simple_view.utils.BeanCopyUtil;
import com.simple.simple_view.utils.RedisCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/*
 *@description: mq消息处理器
 *@author: hisen
 *@Time: 2023/11/2  2:03
 */
@Configuration
@Slf4j
public class RabbitMQLikesHandler {

    @Resource
    UserLikeVideoService userLikeVideoService;
    @Resource
    RedisCache redisCache;
    @Resource
    HotVideoService hotVideoService;
    @Resource
    UserServiceImpl userServiceImpl;
    @Resource
    VideoServiceImpl videoServiceImpl;

    @RabbitListener(queues = RabbitMQConstant.QUEUE_VIDEO_FAVORITE, ackMode = "MANUAL")
    public void onMessage(FavoriteDto favoriteDto,Message message, Channel channel) {
        try {
            UserLikeVideo likeVideo = BeanCopyUtil.copyBean(favoriteDto, UserLikeVideo.class);
            LambdaQueryWrapper<UserLikeVideo>wrapper= new LambdaQueryWrapper<>();
            wrapper.eq(UserLikeVideo::getUserId,likeVideo.getUserId());
            wrapper.eq(UserLikeVideo::getVideoId,likeVideo.getVideoId());
            //删除缓存
            redisCache.deleteObject(RedisSystemParam.VIDEO_PREFIX+favoriteDto.getVideoId());
            if(SystemParam.LIKE_STR.equals(favoriteDto.getIsLike())) {
                if(userLikeVideoService.getOne(wrapper)!=null){
                    channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
                    return;
                }
                //更新榜单
                hotVideoService.incrementScore(favoriteDto.getVideoId().toString(),SystemParam.LIKE_SCORE);
                userLikeVideoService.save(likeVideo);
                //增加用户被赞量
                userServiceImpl.getBaseMapper().incrementLikesById(favoriteDto.getByUserId());
                //增加视频获赞量
                videoServiceImpl.getBaseMapper().incrementLikesById(favoriteDto.getVideoId());
            }else{
                userLikeVideoService.remove(wrapper);
                userServiceImpl.getBaseMapper().decrementLikesById(favoriteDto.getByUserId());
                videoServiceImpl.getBaseMapper().decrementLikesById(favoriteDto.getVideoId());
            }
            //延时双删
            performDelayedDelete(favoriteDto.getVideoId().toString());

            channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private void performDelayedDelete(String videoId) {
        // 延时删除任务
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
        Runnable delayedDeleteTask = () -> {
            try {
                // 执行延时删除操作
                log.info(videoId);
                redisCache.deleteObject(videoId);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        };
        // 延时DEL_TIMEms后执行删除任务
        long initialDelay = RedisSystemParam.DEL_TIME;
        executor.schedule(delayedDeleteTask, initialDelay, TimeUnit.MILLISECONDS);
    }
}